package hotel.meituan.oversea.biz.utils;


import com.alibaba.fastjson.JSON;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.MeituanConstants;
import hotel.base.oversea.utils.Result;
import hotel.meituan.oversea.api.vo.CommonParamsVo;
import hotel.meituan.oversea.biz.task.MeituanSaveApiLogTask;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.*;

@Slf4j
public class MtUtils {
    //公共参数


    private  static String version = MeituanConstants.VERSION;//版本号
    private  static int partnerId = MeituanConstants.BUSINESS_ID;//平台分配给第三方渠道的分销业务ID
    private  static String accesskey = MeituanConstants.ACCESS_KEY;//平台分配给第三方渠道的安全凭证公钥
    private static String apiUrl = MeituanConstants.URL;//请求接口地址
    private static String timestamp = "MtUtils"+String.valueOf(System.currentTimeMillis()/1000);
    /**
     * 构建请求参数
     * @param data 业务参数jsonString，method 接口方法名称
     * @return
     */
    public static String createParamsPost(String data,String method,MeituanSaveApiLogTask meituanSaveApiLogTask) {
        //log.info("{} 美团发送 美团请求接口，请求参数 method={},data={}",MtUtils.timestamp,method.replace(".",""),data);

        /*SysApiLog sysApiLog = new SysApiLog();
        sysApiLog.setId(StringUtil.getUUID()+method);
        sysApiLog.setSystemName("meituan_api_post");
        sysApiLog.setClassName(method);
        sysApiLog.setState(0);
        sysApiLog.setParamJson(data);
        sysApiLog.setCreateTime(new Date());
        sysApiLog.setModifyTime(sysApiLog.getCreateTime());*/

        //公共参数
        long  timestamp=System.currentTimeMillis()/1000;//10位时间戳
        int nonce= new Random().nextInt(Integer.MAX_VALUE);//随机正整数。与timestamp联合使用以防止重放攻击
        //构建请求参数,提交请求
        CommonParamsVo commonParamsVo = new CommonParamsVo();
        commonParamsVo.setMethod(method).setVersion(version).setTimestamp(timestamp).setNonce(nonce).setPartnerId(partnerId).setAccesskey(accesskey).setData(data);
        String signature= MtUtils.createsSignature(commonParamsVo);
        commonParamsVo.setSignature(signature);
        String response = null;
        try {
            response = MtUtils.HttpPost(apiUrl,commonParamsVo);
        }catch (Exception e){
            response = JSON.toJSONString(new Result<>("请求美团接口catch异常："+e.getMessage(),CommonConstants.REQUEST_ERROR));
            e.printStackTrace();
        }

        /*sysApiLog.setJson(response==null?null:JSON.toJSONString(response));
        try{
            meituanSaveApiLogTask.execute(sysApiLog);
        }catch (Exception e){
            log.error("美团发送，请求接口，异步线程保存日志异常 ："+e.getMessage());
            e.printStackTrace();
        }*/
        if(null != response){
            com.alibaba.fastjson.JSONObject responseJson = JSON.parseObject(response);
            if(!"0".equals(String.valueOf(responseJson.get("code")))){
                log.error("{} 美团发送 美团请求接口，响应异常失败： {}", MtUtils.timestamp+method,response);
            }
        }
        //log.info("{} 美团发送 美团请求接口，响应参数 method={},response={}",MtUtils.timestamp,method.replace(".",""),response);
        return response;
    }

    /*public static ResultApiVo getResult(String data, String methodId, Function<String,ResultApiVo> function) {
        try {
            //发起请求
            String response = MtUtils.createParamsPost(data, methodId);
            return function.apply(response);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return new ResultApiVo(ApiConstans.CODE_ERROR, e.getMessage(), null);
        }
    }*/
    /*public static <T> boolean isSuccess(MtBaseResponse<T> response) {
        return "0".equals(response.getCode());
    }*/

    /**
     * 规则构建签名
     * @param params
     * @return
     *
     */
    public static String createsSignature(CommonParamsVo params){
        //排序
        //params=MtUtils.order(params);
      /*  signatureParams.put("method",method);
        signatureParams.put("version",version);
        signatureParams.put("timestamp",timestamp+"");
        signatureParams.put("nonce",nonce+"");
        signatureParams.put("partnerId",partnerId+"");
        signatureParams.put("data",data);
        signatureParams.put("accesskey",accesskey);*/

        String rawSignStr = "accesskey=" + params.getAccesskey() + "&data=" + params.getData()
                + "&method=" + params.getMethod() + "&nonce=" + params.getNonce()
                + "&partnerId=" + params.getPartnerId() + "&timestamp=" + params.getTimestamp()
                + "&version=" + params.getVersion();
        //拼接上除了签名之外的所有数据
        String plainText =rawSignStr;
        /*for (Map.Entry<String, String> entry : params.entrySet()) {
            plainText +=entry.getKey()+"="+entry.getValue()+"&";
        }
        plainText = plainText.substring(0,plainText.length()-1);*/
        //hmacSha1加密并加密后的字节流base64编码
        try {
            //plainText= EncryptUtil.hmacSha1(plainText, MeituanConstants.SECRET_KEY);
            plainText = hmacSha1(plainText, MeituanConstants.SECRET_KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return plainText;
    }
    private static String hmacSha1(String plainText, String secretKey) {
        SecretKeySpec secretKeySpec = new SecretKeySpec(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(secretKey), "HmacSHA1");
        try {
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(secretKeySpec);
            return Base64.encodeBase64String(mac.doFinal(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(plainText)));
        } catch (GeneralSecurityException var5) {
            throw new IllegalArgumentException(var5);
        }
    }


    //发起请求
    public static String HttpPost(String url, Object object) {
        Map<String,String> error = null;
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpClient client = HttpClients.createDefault();
        String respContent = null;
        // json方式
        StringEntity entity = new StringEntity(JSONObject.fromObject(object).toString(),"utf-8");//解决中文乱码问题
        entity.setContentEncoding("UTF-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);

        HttpResponse resp = null;
        try {
            resp = client.execute(httpPost);
            if(resp.getStatusLine().getStatusCode() == 200) {
                HttpEntity he = resp.getEntity();
                respContent = EntityUtils.toString(he,"UTF-8");
            }else{
                error = new HashMap<>();
                error.put("code","1000");
                error.put("message","HttpStatusCode:"+resp.getStatusLine().getStatusCode());
                error.put("index","hhb");
                respContent = JSON.toJSONString(error);
            }
        } catch (Exception e) {
            e.printStackTrace();
            error = new HashMap<>();
            error.put("code","1000");
            error.put("message",e.getMessage());
            error.put("index","hhb");
            respContent = JSON.toJSONString(error);
        }
        finally {
            try {
                client.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //log.info("///////////////////////////////postHttp-respContent："+respContent);
        return respContent;
    }

    //字典序进行升序排列（转化为小写）
    public static Map<String, String> orderttttt(Map<String, String> map) {
        HashMap<String, String> tempMap = new LinkedHashMap<>();
        List<Map.Entry<String, String>> infoIds = new ArrayList<>(map.entrySet());

        Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return (o1.getKey()).toString().compareTo(o2.getKey());
            }
        });

        for (int i = 0; i < infoIds.size(); i++) {
            Map.Entry<String, String> item = infoIds.get(i);
            tempMap.put(item.getKey().toLowerCase(), item.getValue());
        }
        return tempMap;
    }

}
